﻿using AutoMapper;
using ManagementApi.Authorizers;
using ManagementApi.Models;
using ManagementApi.Models.Payroll;
using ManagementApi.Models.Project;
using ManagementApi.Models.System.AuditLog;
using ManagementApi.Mvc;
using ManagementApi.Mvc.ApplicationContexts;
using ManagementApi.Mvc.Authorization;
using ManagementApi.Services;
using ManagementApi.Services.Import;
using ManagementApi.Services.ProjectImport;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Modules;
using Modules.Common;
using Modules.Project;
using Modules.System.Attachment;
using Modules.System.Dept;
using Modules.System.User;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using PmSoft.Entity;
using PmSoft.Exceptions;
using PmSoft.Utilities;

namespace ManagementApi.Controllers.AdminPannel
{
    /// <summary>
    /// 项目管理员-保证金账户
    /// </summary>
    [Route("/api/v1/sysuser/guarantee")]
    [ApiController]
    [Authorize(Roles = "SysUser")]
    public class ProjectGuaranteeController : ControllerBase
    {
        private readonly ProjectGuaranteeAccountService projectGuaranteeAccountService;
        private readonly ProjectGuaranteePaymentService projectGuaranteePaymentService;
        private readonly ProjectGuaranteeRefundService projectGuaranteeRefundService;
        private readonly ProjectGuaranteeIncomeService projectGuaranteeIncomeService;
        private readonly ProjectGuaranteeExpenditureService projectGuaranteeExpenditureService;
        private readonly ProjectGuaranteeExpenditureDetailService projectGuaranteeExpenditureDetailService;
        private readonly ManagementApplicationContext applicationContext;
        private readonly UserService userService;
        private readonly DeptService deptService;
        private readonly SerialNumberService serialNumberService;
        private readonly ExportService exportService;
        private readonly AttachmentService attachmentService;
        private readonly ProjectService projectService;
        private readonly IMapper mapper;
        private readonly ProjectGuaranteeOwnAuthorizer ownAuthorizer;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="projectGuaranteeAccountService"></param>
        /// <param name="applicationContext"></param>
        /// <param name="mapper"></param>
        /// <param name="projectGuaranteePaymentService"></param>
        /// <param name="projectGuaranteeRefundService"></param>
        /// <param name="projectGuaranteeIncomeService"></param>
        /// <param name="projectGuaranteeExpenditureService"></param>
        /// <param name="projectGuaranteeExpenditureDetailService"></param>
        /// <param name="userService"></param>
        /// <param name="deptService"></param>
        /// <param name="serialNumberService"></param>
        /// <param name="attachmentService"></param>
        /// <param name="exportService"></param>
        /// <param name="projectService"></param>
        /// <param name="ownAuthorizer"></param>
        public ProjectGuaranteeController(ProjectGuaranteeAccountService projectGuaranteeAccountService, ManagementApplicationContext applicationContext, IMapper mapper,
            ProjectGuaranteePaymentService projectGuaranteePaymentService, ProjectGuaranteeRefundService projectGuaranteeRefundService,
            ProjectGuaranteeIncomeService projectGuaranteeIncomeService, ProjectGuaranteeExpenditureService projectGuaranteeExpenditureService,
            ProjectGuaranteeExpenditureDetailService projectGuaranteeExpenditureDetailService,
            UserService userService, DeptService deptService, SerialNumberService serialNumberService, AttachmentService attachmentService, ExportService exportService, ProjectService projectService
           , ProjectGuaranteeOwnAuthorizer ownAuthorizer)
        {
            this.projectGuaranteeAccountService = projectGuaranteeAccountService;
            this.applicationContext = applicationContext;
            this.mapper = mapper;
            this.deptService = deptService;
            this.serialNumberService = serialNumberService;
            this.projectGuaranteePaymentService = projectGuaranteePaymentService;
            this.projectGuaranteeRefundService = projectGuaranteeRefundService;
            this.projectGuaranteeExpenditureService = projectGuaranteeExpenditureService;
            this.projectGuaranteeIncomeService = projectGuaranteeIncomeService;
            this.projectGuaranteeExpenditureDetailService = projectGuaranteeExpenditureDetailService;
            this.userService = userService;
            this.attachmentService = attachmentService;
            this.exportService = exportService;
            this.projectService = projectService;
            this.ownAuthorizer = ownAuthorizer;
        }

        #region 保证金账户

        /// <summary>
        /// 新增保证金账户
        /// </summary>
        /// <param name="form"></param>
        /// <returns></returns>
        [HttpPost("account/create")]
        [PermissionCheck("sys:guarantee_account:add")]
        public ApiResult CreateProjectGuaranteeAccount(ProjectGuaranteeAccountEditForm form)
        {
            #region 仅超管和人社角色可操作

            if (applicationContext.CurrentUser is IDeptUser deptUser && (!deptUser.IsRSAdministrator() && !deptUser.IsSuperAdministrator()))
            {
                return ApiResult.Failure("该账户无此权限");
            }

            #endregion 仅超管和人社角色可操作

            if (applicationContext.CurrentUser == null) return ApiResult.Failure("未查询到当前登录用户信息");
            var sysUser = userService.GetUser(applicationContext.CurrentUser.Id) ?? throw new BusinessException("未查询到当前登录用户信息");
            var dept = deptService.GetSysDept(sysUser.DeptId ?? 0) ?? throw new BusinessException("未查询到当前登录用户主管单位信息");
            ProjectGuaranteeAccount entity = new();
            mapper.Map(form, entity);
            entity.Creator = sysUser.Name;
            if (entity.Type == 保证金类型.保证金账户)
            {
                entity.RsName = dept.Name;
            }
            entity.CreateTime = DateTime.Now;
            projectGuaranteeAccountService.Create(entity, form.Attachments.Select(i => i.AttachmentId));
            return ApiResult.Success("创建成功");
        }

        /// <summary>
        /// 编辑保证金账户
        /// </summary>
        /// <param name="id"></param>
        /// <param name="form"></param>
        /// <returns></returns>
        [HttpPut("account/update")]
        [PermissionCheck("sys:guarantee_account:update")]
        public ApiResult UpdateProjectGuaranteeAccount(ProjectGuaranteeAccountEditForm form)
        {
            #region 仅超管和人社角色可操作

            if (applicationContext.CurrentUser is IDeptUser deptUser && (!deptUser.IsRSAdministrator() && !deptUser.IsSuperAdministrator()))
            {
                return ApiResult.Failure("该账户无此权限");
            }

            #endregion 仅超管和人社角色可操作

            var entity = projectGuaranteeAccountService.GetProjectGuaranteeAccount(form.Id ?? 0);
            if (entity == null) return ApiResult.Failure("未查询到保证金账户信息");
            mapper.Map(form, entity);
            projectGuaranteeAccountService.Update(entity, form.Attachments.Select(i => i.AttachmentId));
            return ApiResult.Success("修改成功");
        }

        /// <summary>
        /// 删除保证金账户
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        [HttpDelete("account/{ids}")]
        [PermissionCheck("sys:guarantee_account:delete")]
        public ApiResult DeleteProjectGuaranteeAccount(string ids)
        {
            #region 仅超管和人社角色可操作

            if (applicationContext.CurrentUser is IDeptUser deptUser && (!deptUser.IsRSAdministrator() && !deptUser.IsSuperAdministrator()))
            {
                return ApiResult.Failure("该账户无此权限");
            }

            #endregion 仅超管和人社角色可操作

            projectGuaranteeAccountService.Deleted(ValueUtility.ConvertToList<int>(ids));
            return ApiResult.Success("删除成功");
        }

        /// <summary>
        /// 保证金账户表单数据
        /// </summary>
        /// <param name="id">角色ID</param>
        /// <returns></returns>
        [HttpGet("account/{id}")]
        public ApiResult<ProjectGuaranteeAccountDto> GetProjectGuaranteeAccount(int id)
        {
            var user = userService.GetUser(applicationContext.CurrentUser?.Id ?? 0);
            if (user == null) return ApiResult<ProjectGuaranteeAccountDto>.Failure("未查询到当前登录用户信息");
            var dept = deptService.GetSysDept(user.DeptId ?? 0);
            if (dept == null) return ApiResult<ProjectGuaranteeAccountDto>.Failure("未查询到当前登录用户主管单位信息");

            ProjectGuaranteeAccountDto projectGuaranteeAccountDto = new ProjectGuaranteeAccountDto();
            if (id == 0)
            {
                projectGuaranteeAccountDto.RsName = dept.Name;
                projectGuaranteeAccountDto.Code = serialNumberService.GetNumAndSerialNumber(SerialNumberType.保证金).Code;
                return ApiResult<ProjectGuaranteeAccountDto>.Success(projectGuaranteeAccountDto);
            }
            ProjectGuaranteeAccount? data = projectGuaranteeAccountService.GetProjectGuaranteeAccount(id);
            if (data == null)
                return ApiResult<ProjectGuaranteeAccountDto>.Failure("保证金账户不存在");

            return ApiResult<ProjectGuaranteeAccountDto>.Success(data.AsDto());
        }

        /// <summary>
        /// 获取保证金账户列表(分页)
        /// </summary>
        /// <param name="query">查询条件</param>
        /// <param name="pageNum">页码</param>
        /// <param name="pageSize">每页数量</param>
        /// <returns></returns>
        [HttpGet("account/page")]
        public ApiResult<PageDto<ProjectGuaranteeAccountDto>> QueryProjectGuarantees([FromQuery] ProjectGuaranteeAccountQuery query, int pageNum = 1, int pageSize = 20)
        {
            var data = projectGuaranteeAccountService.GetProjectGuaranteeAccounts(query, pageNum, pageSize);
            var dtos = data.AsPageDto(source => { return source.AsDto(); });
            return ApiResult<PageDto<ProjectGuaranteeAccountDto>>.Success(dtos);
        }

        #endregion 保证金账户

        #region 保证金缴纳信息

        /// <summary>
        /// 获取保证金账户列表（不包括保函该处查询只用于创建保证金收入信息与保证金支出信息）
        /// </summary>
        /// <param name="query">查询条件</param>
        /// <param name="pageNum">页码</param>
        /// <param name="pageSize">每页数量</param>
        /// <returns></returns>
        [HttpGet("payment/active_page")]
        public ApiResult<PageDto<ProjectGuaranteePaymentDto>> GetActiveProjectGuaranteePayments([FromQuery] ProjectGuaranteePaymentQuery query, int pageNum = 1, int pageSize = 20)
        {
            query.Status = 保证金状态.有效;//查询有效的保证金
            query.HasReturn = false;//查询未退还的保证金
            // query.AccountType = 保证金类型.保证金账户;//只查询保证金的账户
            var data = projectGuaranteePaymentService.GetProjectGuaranteePayments(query, pageNum, pageSize);
            var dtos = data.AsPageDto(source => { return source.AsDto(applicationContext); });
            return ApiResult<PageDto<ProjectGuaranteePaymentDto>>.Success(dtos);
        }

        /// <summary>
        /// 获取保证金账户列表
        /// </summary>
        /// <param name="query">查询条件</param>
        /// <param name="pageNum">页码</param>
        /// <param name="pageSize">每页数量</param>
        /// <returns></returns>
        [HttpGet("payment/page")]
        public ApiResult<PageDto<ProjectGuaranteePaymentDto>> GetProjectGuaranteePayments([FromQuery] ProjectGuaranteePaymentQuery query, int pageNum = 1, int pageSize = 20)
        {
           // query.Status = 保证金状态.有效;//查询有效的保证金
           // query.HasReturn = false;//查询未退还的保证金
            // query.AccountType = 保证金类型.保证金账户;//只查询保证金的账户
            var data = projectGuaranteePaymentService.GetProjectGuaranteePayments(query, pageNum, pageSize);
            var dtos = data.AsPageDto(source => { return source.AsDto(applicationContext); });
            return ApiResult<PageDto<ProjectGuaranteePaymentDto>>.Success(dtos);
        }

        /// <summary>
        /// 保证金账户表单数据
        /// </summary>
        /// <param name="id">角色ID</param>
        /// <returns></returns>
        [HttpGet("payment/{id}")]
        public ApiResult<ProjectGuaranteePaymentDto> GetProjectGuaranteePayment(int id)
        {
            var data = projectGuaranteePaymentService.GetProjectGuaranteePayment(id);
            if (data == null)
                return ApiResult<ProjectGuaranteePaymentDto>.Failure("保证金账户不存在");

            return ApiResult<ProjectGuaranteePaymentDto>.Success(data.AsDto(applicationContext));
        }

        /// <summary>
        /// 通过保证金账户获取所有的缴纳信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("payment/list/{id}")]
        public ApiResult<IEnumerable<ProjectGuaranteePaymentDto>> GetProjectGuaranteePaymentsByAccountId(int id)
        {
            var data = projectGuaranteePaymentService.GetProjectGuaranteePayments(id);
            List<ProjectGuaranteePaymentDto> dtos = new();
            foreach (var item in data)
            {
                dtos.Add(item.AsDto(applicationContext));
            }
            return ApiResult<IEnumerable<ProjectGuaranteePaymentDto>>.Success(dtos);
        }

        /// <summary>
        /// 审核保证金
        /// </summary>
        /// <param name="auditForm"></param>
        /// <returns></returns>
        [HttpPut("payment/audit")]
        [PermissionCheck("sys:guarantee_payment:audit")]
        public ApiResult AuditProjectGuaranteePayment(ProjectGuaranteePaymentAuditForm auditForm)
        {
            var projectGuaranteePayment = projectGuaranteePaymentService.GetProjectGuaranteePayment(auditForm.Id);
            if (projectGuaranteePayment == null) return ApiResult.Failure("审核的缴纳账户不存在");

            #region 验证数据权限

            ownAuthorizer.CheckAndThrowIfOwnAuthenticationFailed(projectGuaranteePayment.ProjectId);

            #endregion 验证数据权限

            projectGuaranteePayment.Status = auditForm.Status;
            projectGuaranteePayment.CheckReason = auditForm.CheckReason;
            projectGuaranteePaymentService.Audit(projectGuaranteePayment);
            return ApiResult.Success("操作成功");
        }

        #endregion 保证金缴纳信息

        #region 保证金退还信息

        /// <summary>
        /// 退还信息详情
        /// </summary>
        /// <param name="id">退还记录Id</param>
        /// <param name="guaranteePaymentId">角色ID</param>
        /// <returns></returns>
        [HttpGet("refund/{id}")]
        public ApiResult<ProjectGuaranteeRefundDto> GetProjectGuaranteeRefund(int id, int guaranteePaymentId)
        {
            var user = userService.GetUser(applicationContext.CurrentUser?.Id ?? 0);
            if (user == null) return ApiResult<ProjectGuaranteeRefundDto>.Failure("未查询到当前登录用户信息");
            var dept = deptService.GetSysDept(user.DeptId ?? 0);
            if (dept == null) return ApiResult<ProjectGuaranteeRefundDto>.Failure("未查询到当前登录用户主管单位信息");
            var data = projectGuaranteeRefundService.GetProjectGuaranteeRefund(id);
            if (data == null)
                return ApiResult<ProjectGuaranteeRefundDto>.Failure("退还记录不存在");
            data.RefundOrganization = dept.Name;
            data.RefundOrganizationCode = dept.Code;
            return ApiResult<ProjectGuaranteeRefundDto>.Success(data.AsDto(applicationContext));
        }

        /// <summary>
        /// 获取保证金账户列表(分页)
        /// </summary>
        /// <param name="query">查询条件</param>
        /// <param name="pageNum">页码</param>
        /// <param name="pageSize">每页数量</param>
        /// <returns></returns>
        [HttpGet("refund/page")]
        public ApiResult<PageDto<ProjectGuaranteeRefundDto>> GetProjectGuaranteeRefunds([FromQuery] ProjectGuaranteeRefundQuery query, int pageNum = 1, int pageSize = 20)
        {
            var data = projectGuaranteeRefundService.GetProjectGuaranteeRefunds(query, pageNum, pageSize);
            var dtos = data.AsPageDto(source => { return source.AsDto(applicationContext); });
            return ApiResult<PageDto<ProjectGuaranteeRefundDto>>.Success(dtos);
        }

        /// <summary>
        /// 审核退还记录
        /// </summary>
        /// <param name="auditForm"></param>
        /// <returns></returns>
        [HttpPut("refund/audit")]
        [PermissionCheck("sys:guarantee_refund:audit")]
        public ApiResult AuditProjectGuaranteeRefund(ProjectGuaranteeRefundAuditForm auditForm)
        {
            var projectGuaranteeRefund = projectGuaranteeRefundService.GetProjectGuaranteeRefund(auditForm.Id);
            if (projectGuaranteeRefund == null) return ApiResult.Failure("退还申请不存在");

            #region 验证数据权限

            ownAuthorizer.CheckAndThrowIfOwnAuthenticationFailed(projectGuaranteeRefund.ProjectId);

            #endregion 验证数据权限

            mapper.Map(auditForm, projectGuaranteeRefund);
            projectGuaranteeRefundService.RefundPayment(projectGuaranteeRefund);
            return ApiResult.Success("操作成功");
        }

        #endregion 保证金退还信息

        #region 账户收入信息

        /// <summary>
        /// 新增账户收入信息
        /// </summary>
        /// <param name="form"></param>
        /// <returns></returns>
        [HttpPost("income/create")]
        [PermissionCheck("sys:guarantee_income:add")]
        public ApiResult CreateProjectGuaranteeIncome(ProjectGuaranteeIncomeEditForm form)
        {
            var payment = projectGuaranteePaymentService.GetProjectGuaranteePayment(form.GuaranteePaymentId ?? 0) ?? throw new BusinessException("保证金缴存信息不存在");

            #region 验证数据权限

            ownAuthorizer.CheckAndThrowIfOwnAuthenticationFailed(payment.ProjectId);

            #endregion 验证数据权限

            ProjectGuaranteeIncome entity = new();
            mapper.Map(form, entity);
            entity.CreateTime = DateTime.Now;
            entity.Creator = applicationContext.CurrentUser?.Name ?? string.Empty;
            projectGuaranteeIncomeService.Create(entity);
            return ApiResult.Success("创建成功");
        }

        /// <summary>
        /// 删除收入信息
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        [HttpDelete("income/{ids}")]
        [PermissionCheck("sys:guarantee_income:delete")]
        public ApiResult DeleteProjectGuaranteeIncome(string ids)
        {
            var entitys = projectGuaranteeIncomeService.GetProjectGuaranteeIncomes(ValueUtility.ConvertToList<int>(ids));

            #region 验证数据权限

            ownAuthorizer.CheckAndThrowIfOwnAuthenticationFailed(entitys.Select(i => i.ProjectId));

            #endregion 验证数据权限

            projectGuaranteeIncomeService.Deleted(ValueUtility.ConvertToList<int>(ids));
            return ApiResult.Success("删除成功");
        }

        /// <summary>
        /// 收入信息表单数据
        /// </summary>
        /// <param name="id">角色ID</param>
        /// <returns></returns>
        [HttpGet("income/{id}")]
        public ApiResult<ProjectGuaranteeIncomeDto> GetProjectGuaranteeIncome(int id)
        {
            ProjectGuaranteeIncome? data = projectGuaranteeIncomeService.GetProjectGuaranteeIncome(id);
            if (data == null)
                return ApiResult<ProjectGuaranteeIncomeDto>.Failure("收支信息不存在");

            return ApiResult<ProjectGuaranteeIncomeDto>.Success(data.AsDto(applicationContext));
        }

        /// <summary>
        /// 获取收入信息列表(分页)
        /// </summary>
        /// <param name="query">查询条件</param>
        /// <param name="pageNum">页码</param>
        /// <param name="pageSize">每页数量</param>
        /// <returns></returns>
        [HttpGet("income/page")]
        public ApiResult<PageDto<ProjectGuaranteeIncomeDto>> QueryProjectGuaranteeIncomes([FromQuery] ProjectGuaranteeIncomeQuery query, int pageNum = 1, int pageSize = 20)
        {
            var data = projectGuaranteeIncomeService.GetProjectGuaranteeIncomes(query, pageNum, pageSize);
            var dtos = data.AsPageDto(source => { return source.AsDto(applicationContext); });
            return ApiResult<PageDto<ProjectGuaranteeIncomeDto>>.Success(dtos);
        }

        /// <summary>
        /// 导出Excel（收入明细）
        /// </summary>
        /// <returns></returns>
        [HttpGet("income/export")]
        [PermissionCheck("sys:guarantee_income:export")]
        public IActionResult ExportProjectGuaranteeIncomes([FromQuery] ProjectGuaranteeIncomeQuery query, int pageIndex = 1, int pageSize = 9999)
        {
            var data = projectGuaranteeIncomeService.GetProjectGuaranteeIncomes(query, pageIndex, pageSize);
            IWorkbook workbook = ExcelExportHelper.ExportToExcel(data.AsExportDto().ToList());

            // 将工作簿保存到内存流中
            using (MemoryStream memoryStream = new MemoryStream())
            {
                workbook.Write(memoryStream);
                // 返回文件内容结果
                return File(memoryStream.ToArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", $"收入明细_{DateTime.Now.ToString("yyyyMMddHHmmss ")}.xlsx");
            }
        }

        #endregion 账户收入信息

        #region 账户支出信息

        /// <summary>
        /// 新增账户支出信息
        /// </summary>
        /// <param name="form"></param>
        /// <returns></returns>
        [HttpPost("expenditure/create")]
        [PermissionCheck("sys:guarantee_expenditure:add")]
        public ApiResult CreateProjectGuaranteeExpenditure(ProjectGuaranteeExpenditureEditForm form)
        {
            var payment = projectGuaranteePaymentService.GetProjectGuaranteePayment(form.GuaranteePaymentId ?? 0) ?? throw new BusinessException("保证金缴存信息不存在");

            #region 验证数据权限

            ownAuthorizer.CheckAndThrowIfOwnAuthenticationFailed(payment.ProjectId);

            #endregion 验证数据权限

            ProjectGuaranteeExpenditure entity = new();
            mapper.Map(form, entity);
            entity.CreateTime = DateTime.Now;
            entity.Creator = applicationContext.CurrentUser?.Name ?? string.Empty;
            List<ProjectGuaranteeExpenditureDetail> details = new();
            foreach (var detail in form.Details)
            {
                details.Add(new ProjectGuaranteeExpenditureDetail()
                {
                    CardNo = detail.CardNo,
                    UserName = detail.UserName,
                    Amount = detail.Amount,
                    PayType = detail.PayType
                });
            }
            projectGuaranteeExpenditureService.Create(entity, details);
            return ApiResult.Success("创建成功");
        }

        ///// <summary>
        ///// 通过临时附件ID初始化支出明细
        ///// </summary>
        ///// <param name="attachmentId"></param>
        ///// <returns></returns>
        //[HttpGet("expenditure/import")]
        //public ApiResult<IEnumerable<ProjectGuaranteeExpenditureDetailForm>> InitExpenditureDetail(string attachmentId)
        //{
        //    var attachmentInfo = attachmentService.GetAttachmentInfo(attachmentId);
        //    if (attachmentInfo == null)
        //    {
        //        return ApiResult<IEnumerable<ProjectGuaranteeExpenditureDetailForm>>.Failure("请上传支付明细表");
        //    }
        //    string tempPath = Path.Combine(Environment.CurrentDirectory, "temps", attachmentInfo.Name);
        //    var list = ImportExcelUtil<ProjectGuaranteeExpenditureDetailForm>.InputExcel(tempPath);
        //    return ApiResult<IEnumerable<ProjectGuaranteeExpenditureDetailForm>>.Success(list);
        //}

        /// <summary>
        /// 导入支付信息明细校验
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        [HttpPost("expenditure/import")]
        public ApiResult<IEnumerable<ProjectGuaranteeExpenditureDetailForm>> UploadExcel(IFormFile file)
        {
            try {
                var list = ImportExcelUtil<ProjectGuaranteeExpenditureDetailForm>.InputExcel(file);
                return ApiResult<IEnumerable<ProjectGuaranteeExpenditureDetailForm>>.Success(list);

            }
            catch (Exception ex)
            {
                throw new BusinessException(ex.Message);
            }
        }



        /// <summary>
        /// 导出支出明细模板
        /// </summary>
        /// <returns></returns>
        [HttpGet("expenditure/exportTemplate")]
        [PermissionCheck("sys:guarantee_expenditure:export")]
        public IActionResult ExportDetailTemplet()
        {
            #region 导出部分

            // 创建一个新的Excel工作簿
            IWorkbook workbook = new XSSFWorkbook();

            // 创建一个新的工作表
            ISheet sheet = workbook.CreateSheet("Sheet1");
            // 创建列并设置最小宽度
            int columnWidth = 20;
            int columnIndex = 0;
            sheet.SetColumnWidth(columnIndex, columnWidth * 256); // 设定列宽度，参数为1/256个字符宽度

            // 自动调整列宽
            for (int i = 0; i < 4; i++)
            {
                // 自动调整列宽
                //sheet.AutoSizeColumn(i);
                sheet.SetColumnWidth(i, Math.Max(columnWidth * 256, sheet.GetColumnWidth(i)));
            }

            #region 表格部分

            exportService.CellRange(sheet, workbook, 0, 0, "务工人员公民身份号码", "务工人员姓名", "工资支付金额", "工资支付方式", "");

            #endregion 表格部分

            // 将工作簿保存到内存流中
            using (MemoryStream memoryStream = new MemoryStream())
            {
                workbook.Write(memoryStream);

                // 设置要下载的文件名
                string fileName = $"支出明细模板.xlsx";

                // 返回文件内容结果
                return File(memoryStream.ToArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileName);
            }

            #endregion 导出部分
        }

        /// <summary>
        /// 删除支出信息
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        [HttpDelete("expenditure/{ids}")]
        [PermissionCheck("sys:guarantee_expenditure:delete")]
        public ApiResult DeleteProjectGuaranteeExpenditure(string ids)
        {
            var entitys = projectGuaranteeExpenditureService.GetProjectGuaranteeExpenditures(ValueUtility.ConvertToList<int>(ids));

            #region 验证数据权限

            ownAuthorizer.CheckAndThrowIfOwnAuthenticationFailed(entitys.Select(i => i.ProjectId));

            #endregion 验证数据权限

            projectGuaranteeExpenditureService.Deleted(ValueUtility.ConvertToList<int>(ids));
            return ApiResult.Success("删除成功");
        }

        /// <summary>
        /// 支出信息表单数据
        /// </summary>
        /// <param name="id">角色ID</param>
        /// <returns></returns>
        [HttpGet("expenditure/{id}")]
        public ApiResult<ProjectGuaranteeExpenditureDto> GetProjectGuaranteeExpenditure(int id)
        {
            ProjectGuaranteeExpenditure? data = projectGuaranteeExpenditureService.GetProjectGuaranteeExpenditure(id);
            if (data == null)
                return ApiResult<ProjectGuaranteeExpenditureDto>.Failure("支出信息不存在");

            return ApiResult<ProjectGuaranteeExpenditureDto>.Success(data.AsDto(applicationContext));
        }

        /// <summary>
        /// 获取支出明细详情
        /// </summary>
        /// <param name="guaranteeExpenditureId">明细Id</param>
        /// <returns></returns>
        [HttpGet("expenditure/detail/{guaranteeExpenditureId}")]
        public ApiResult<IEnumerable<ProjectGuaranteeExpenditureDetail>> GetProjectGuaranteeExpenditureDetail(int guaranteeExpenditureId)
        {
            var data = projectGuaranteeExpenditureDetailService.GetProjectGuaranteeExpenditureDetailsByGuaranteeExpenditureId(guaranteeExpenditureId);
            return ApiResult<IEnumerable<ProjectGuaranteeExpenditureDetail>>.Success(data);
        }

        /// <summary>
        /// 获取支出信息列表(分页)
        /// </summary>
        /// <param name="query">查询条件</param>
        /// <param name="pageNum">页码</param>
        /// <param name="pageSize">每页数量</param>
        /// <returns></returns>
        [HttpGet("expenditure/page")]
        public ApiResult<PageDto<ProjectGuaranteeExpenditureDto>> QueryProjectGuaranteeExpenditure([FromQuery] ProjectGuaranteeExpenditureQuery query, int pageNum = 1, int pageSize = 20)
        {
            var data = projectGuaranteeExpenditureService.GetProjectGuaranteeExpenditures(query, pageNum, pageSize);
            var dtos = data.AsPageDto(source => { return source.AsDto(applicationContext); });
            return ApiResult<PageDto<ProjectGuaranteeExpenditureDto>>.Success(dtos);
        }

        #endregion 账户支出信息
    }
}